package com.ecarx.vhaltests.hy11.testcases.tcam;

import static com.ecarx.xui.adaptapi.car.base.ICarFunction.COMMON_VALUE_OFF;
import static com.ecarx.xui.adaptapi.car.base.ICarFunction.COMMON_VALUE_ON;
import static com.ecarx.xui.adaptapi.car.vehicle.IVehicle.SETTING_FUNC_TCAM_DTAT_UPLOAD;

import android.car.VehicleAreaType;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;

import androidx.test.platform.app.InstrumentationRegistry;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;

import android.util.Log;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SettingFunDataUploadTest extends VhalUnitTestBase {
    
    private static final String TAG = "SettingFunDataUploadTest";

    private static int halValue = -1;
    private static int halStatus = -1;
    final static Object lock = new Object();
    private static final IpcpClient ipcpClient = new IpcpClient();

    @BeforeClass
    public static void testInit() {
        Log.d(TAG, "testInit");
        IWrapper wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        IWrapper.IPropertyId propertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, SETTING_FUNC_TCAM_DTAT_UPLOAD);
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, propertyId.getPropertyId(), CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig();
    }


    @Test
    public void testStatusNoActive() {
        Log.d(TAG, "testStatusNoActive");
        IWrapper wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        IWrapper.IPropertyId propertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, SETTING_FUNC_TCAM_DTAT_UPLOAD);
        setCEM(VehicleConstants.USG_MODE_ACTIVE, VehicleConstants.CAR_MODE_NOMAL);
        lockWait();
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(propertyId.getPropertyId(), VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        //Assert.assertEquals(CarPropertyValue.STATUS_UNAVAILABLE, halStatus); // PropertyStatus::NotActive
        Assert.assertFalse(isAvail);

    }

    @Test
    public void testStatusActive() {
        Log.d(TAG, "testStatusActive");
        IWrapper wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        IWrapper.IPropertyId propertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, SETTING_FUNC_TCAM_DTAT_UPLOAD);
        setCEM(VehicleConstants.USG_MODE_DRIVING, VehicleConstants.CAR_MODE_NOMAL);
        lockWait();
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(propertyId.getPropertyId(), VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        //Assert.assertEquals(CarPropertyValue.STATUS_AVAILABLE, halStatus); // PropertyStatus::Active
        Assert.assertTrue(isAvail);
    }

    @Test
    public void testSetAndGetValOn() {
        Log.d(TAG, "testSetAndGetValOn");
        testSetAndGetVal(true);
    }

   @Test
    public void testSetAndGetValOff() {
        Log.d(TAG, "testSetAndGetValOff");
        testSetAndGetVal(false);
    }

    public void testSetAndGetVal(boolean value) {
        delay(2000);
        setCEM(VehicleConstants.USG_MODE_CONVENIENCE, VehicleConstants.CAR_MODE_NOMAL);
        delay(2000);
        setAutoShowModeOn(value);
        delay(2000);
        lockWait();
        Assert.assertEquals(value, getValue());; // PropertyStatus::Active
    }

    private boolean getValue() {
        IWrapper wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        IWrapper.IPropertyId propertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, SETTING_FUNC_TCAM_DTAT_UPLOAD);
        int AREA_ID = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
        delay(2000);
        return mCarPropertyMgr.getBooleanProperty(propertyId.getPropertyId(), AREA_ID);
    }

    private static final CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                halValue = (int) carPropertyValue.getValue();
                halStatus = carPropertyValue.getStatus();
                Log.e(TAG, "onChangeEvent======halValue:" + halValue);
                Log.e(TAG, "onChangeEvent======halStatus:" + halStatus);

                synchronized (lock) {
                    lock.notify();
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {
        }
    };

    public void lockWait() {
        try {
            synchronized (lock) {
                lock.wait(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void unLock() {
        synchronized (lock) {
            lock.notify();
        }
    }

    private void setAutoShowModeOn(boolean on) {
        IWrapper wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        IWrapper.IPropertyId wrapperProperty = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, SETTING_FUNC_TCAM_DTAT_UPLOAD);
        int propertyId = wrapperProperty.getPropertyId();
        int AREA_ID = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
        delay();
        mCarPropertyMgr.setBooleanProperty(propertyId, AREA_ID, on);
        //Assert.assertEquals(wrapperProperty.getPropertyValue(COMMON_VALUE_ON).intValue(), mCarPropertyMgr.getIntProperty(propertyId, AREA_ID));
    }

    public void setCEM(int usgMode, int carMode) {
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1UsgModSts", "vehModMngtGlbSafe1CarModSts1"};
        int[] cemValues = {usgMode, carMode};
        boolean cemResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(cemResult);
        delay();
    }


    private static void setConfig() {
        Log.d(TAG, "setConfig");
        int ccSvcId = 135;
        int[] ccOperIds = {200};
        int vgmSvcId = 37;
        int[] vgmOperIds = {999};
        int vddmSvcId = 48;
        int[] vddmOperIds = {999};
        boolean retCc = ipcpClient.setConfig(ccSvcId, ccOperIds);
        Assert.assertTrue(retCc);
        boolean retVgm = ipcpClient.setConfig(vgmSvcId, vgmOperIds);
        Assert.assertTrue(retVgm);
        boolean vddmVgm = ipcpClient.setConfig(vddmSvcId, vddmOperIds);
        Assert.assertTrue(vddmVgm);
    }

    public void setCarConfig(int cc13) {
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] configs = {13};
        int[] values = {cc13};
        boolean ccResult = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(ccResult);
        delay();
    }

}